-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
26df603
commit 7d28d0b
Showing
10 changed files
with
563 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
export * from "./bitcoin"; | ||
export * from "./ethereum"; | ||
export * from "./thorchain"; | ||
export * from "./ledger"; | ||
export * from "./transport"; | ||
export * from "./utils"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
export enum ErrorCode { | ||
NoError = 0x9000, | ||
} | ||
|
||
export const CLA = 0x55; | ||
export const CHUNK_SIZE = 250; | ||
export const APP_KEY = "CSM"; | ||
|
||
export const INS = { | ||
GET_VERSION: 0x00, | ||
INS_PUBLIC_KEY_SECP256K1: 0x01, // Obsolete | ||
SIGN_SECP256K1: 0x02, | ||
GET_ADDR_SECP256K1: 0x04, | ||
}; | ||
|
||
export const PAYLOAD_TYPE = { | ||
INIT: 0x00, | ||
ADD: 0x01, | ||
LAST: 0x02, | ||
}; | ||
|
||
export const P1_VALUES = { | ||
ONLY_RETRIEVE: 0x00, | ||
SHOW_ADDRESS_IN_DEVICE: 0x01, | ||
}; | ||
|
||
const ERROR_DESCRIPTION = { | ||
1: "U2F: Unknown", | ||
2: "U2F: Bad request", | ||
3: "U2F: Configuration unsupported", | ||
4: "U2F: Device Ineligible", | ||
5: "U2F: Timeout", | ||
14: "Timeout", | ||
0x9000: "No errors", | ||
0x9001: "Device is busy", | ||
0x6802: "Error deriving keys", | ||
0x6400: "Execution Error", | ||
0x6700: "Wrong Length", | ||
0x6982: "Empty Buffer", | ||
0x6983: "Output buffer too small", | ||
0x6984: "Data is invalid", | ||
0x6985: "Conditions not satisfied", | ||
0x6986: "Transaction rejected", | ||
0x6a80: "Bad key handle", | ||
0x6b00: "Invalid P1/P2", | ||
0x6d00: "Instruction not supported", | ||
0x6e00: "App does not seem to be open", | ||
0x6f00: "Unknown error", | ||
0x6f01: "Sign/verify error", | ||
}; | ||
|
||
export function errorCodeToString(statusCode: any) { | ||
if (statusCode in ERROR_DESCRIPTION) return ERROR_DESCRIPTION[statusCode as 1]; | ||
return `Unknown Status Code: ${statusCode}`; | ||
} | ||
|
||
export function processErrorResponse(response: any) { | ||
if (response) { | ||
if ( | ||
typeof response === "object" && | ||
response !== null && | ||
!(response instanceof Array) && | ||
!(response instanceof Date) | ||
) { | ||
if (Object.prototype.hasOwnProperty.call(response, "statusCode")) { | ||
return { | ||
return_code: response.statusCode, | ||
error_message: errorCodeToString(response.statusCode), | ||
}; | ||
} | ||
|
||
if ( | ||
Object.prototype.hasOwnProperty.call(response, "return_code") && | ||
Object.prototype.hasOwnProperty.call(response, "error_message") | ||
) { | ||
return response; | ||
} | ||
} | ||
return { | ||
return_code: 0xffff, | ||
error_message: response.toString(), | ||
}; | ||
} | ||
|
||
return { | ||
return_code: 0xffff, | ||
error_message: response.toString(), | ||
}; | ||
} | ||
|
||
export async function getVersion(transport: any) { | ||
return transport.send(CLA, INS.GET_VERSION, 0, 0).then((response: any) => { | ||
const errorCodeData = response.slice(-2); | ||
const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; | ||
|
||
let targetId = 0; | ||
if (response.length >= 9) { | ||
targetId = (response[5] << 24) + (response[6] << 16) + (response[7] << 8) + (response[8] << 0); | ||
} | ||
|
||
return { | ||
return_code: returnCode, | ||
error_message: errorCodeToString(returnCode), | ||
// /// | ||
test_mode: response[0] !== 0, | ||
major: response[1], | ||
minor: response[2], | ||
patch: response[3], | ||
device_locked: response[4] === 1, | ||
target_id: targetId.toString(16), | ||
}; | ||
}, processErrorResponse); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { CLA, ErrorCode, errorCodeToString, INS, PAYLOAD_TYPE, processErrorResponse } from "./common"; | ||
|
||
const signSendChunkv1 = async (app: any, chunkIdx: any, chunkNum: any, chunk: any) => { | ||
return app.transport | ||
.send(CLA, INS.SIGN_SECP256K1, chunkIdx, chunkNum, chunk, [ErrorCode.NoError, 0x6984, 0x6a80]) | ||
.then((response: any) => { | ||
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")}`; | ||
} | ||
|
||
let signature = null; | ||
if (response.length > 2) { | ||
signature = response.slice(0, response.length - 2); | ||
} | ||
|
||
return { | ||
signature, | ||
return_code: returnCode, | ||
error_message: errorMessage, | ||
}; | ||
}, processErrorResponse); | ||
}; | ||
|
||
export const serializePathv2 = (path: any) => { | ||
if (!path || path.length !== 5) { | ||
throw new Error("Invalid path."); | ||
} | ||
|
||
const buf = Buffer.alloc(20); | ||
buf.writeUInt32LE(0x80000000 + path[0], 0); | ||
buf.writeUInt32LE(0x80000000 + path[1], 4); | ||
buf.writeUInt32LE(0x80000000 + path[2], 8); | ||
buf.writeUInt32LE(path[3], 12); | ||
buf.writeUInt32LE(path[4], 16); | ||
|
||
return buf; | ||
}; | ||
|
||
export const signSendChunkv2 = async (app: any, chunkIdx: any, chunkNum: any, chunk: any) => { | ||
let payloadType = PAYLOAD_TYPE.ADD; | ||
if (chunkIdx === 1) { | ||
payloadType = PAYLOAD_TYPE.INIT; | ||
} | ||
if (chunkIdx === chunkNum) { | ||
payloadType = PAYLOAD_TYPE.LAST; | ||
} | ||
|
||
return signSendChunkv1(app, payloadType, 0, chunk); | ||
}; | ||
|
||
export const publicKeyv2 = async (app: any, data: any) => { | ||
return app.transport.send(CLA, INS.GET_ADDR_SECP256K1, 0, 0, data, [ErrorCode.NoError]).then((response: any) => { | ||
const errorCodeData = response.slice(-2); | ||
const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; | ||
const compressedPk = Buffer.from(response.slice(0, 33)); | ||
|
||
return { | ||
pk: "OBSOLETE PROPERTY", | ||
compressed_pk: compressedPk, | ||
return_code: returnCode, | ||
error_message: errorCodeToString(returnCode), | ||
}; | ||
}, processErrorResponse); | ||
}; |
Oops, something went wrong.